// 云函数入口文件
const cloud = require('wx-server-sdk');
const random = require('random');
const _ = require('lodash');
const moment = require('moment');

cloud.init();
const db = cloud.database();

/**
 * 云函数入口函数
 * 验证抽奖码，验证通过后返回中奖位置
 * @param {*} event 
 * @param {*} context 
 */
exports.main = async (event, context) => {
  const { code, version } = event;
  if (version !== '2.0.0') return { status: -3, code: 9990, message: '请使用新版本' };
  console.log('校验 code 是否合法：', code);
  const wxContext = cloud.getWXContext();
  // 校验是否可以参与活动
  const verify_res = await verifyAction(wxContext.OPENID, code);
  if (verify_res.code !== 0) return { status: -1, code: verify_res.code, message: verify_res.message };
  // 随机奖品
  const { award, luckNumber } = await randomAward();
  if (_.isEmpty(award)) return { status: -2, code: 9999, message: '活动已结束' };
  const realLuckPosition = award.luck_position;
  const luckPosition = realLuckPosition % 7;
  // 生成领奖码
  const awardCode = random.int(100000, 999999);
  console.log('中奖位置：', luckPosition);
  // 初次保存中奖信息，后续需要前端完善领奖人信息
  const lottery_time = moment().format('YYYY-MM-DD HH:mm:ss');
  const award_amount = 1;
  const lottery_record = {
    openid: wxContext.OPENID,
    award_id: award._id,
    award_name: award.name,
    award_icon: award.icon,
    award_luck_ranges: award.luck_ranges,
    award_amount,
    award_code: awardCode,
    lottery_code: code,
    luck_number: luckNumber,
    luckluck_position: luckPosition,
    created_time: lottery_time,
  };
  await db.collection('lottery_record').add({ data: lottery_record });
  // 更新奖品库存
  await db.collection('lottery_award').doc(award._id).update({ data: { used: db.command.inc(award_amount) } });

  return {
    status: 0,
    luckNumber,
    luckPosition,
    realLuckPosition,
    awardCode
  }
}

/**
 * 随机本次奖品
 */
const randomAward = async () => {
  // 获取抽奖奖品列表
  const award_res = await db.collection('lottery_award').get();
  const award_list = award_res.data || [];
  // 计算随机数的范围
  // const min = award_list[0].luck_ranges[0];
  // const max = award_list[9].luck_ranges[1];
  const min = 1;
  const max = 10000;
  const luckNumber = random.int(min, max);
  // 计算 luckPosition
  let luckIndex = 0;
  _.forEach(award_list, (award, index) => {
    award.used = award.used || 0;
    const { luck_ranges } = award;
    // 如果落入当前区间，luckIndex 为当前 index
    if (luckNumber >= luck_ranges[0] && luckNumber <= luck_ranges[1]) luckIndex = index;
  });
  let award = award_list[luckIndex];
  console.log('第一次 award', award);
  // 检查当前奖品的库存，如果库存不足，则选取一个概率最大的奖品为当前奖品
  if (award.quantity <= award.used) {
    award = _.find(award_list, item => { return item.quantity > item.used });
    console.log('奖品数量不足，进行替换', award);
  }
  return { award, luckNumber };
}

/**
 * 校验是否可以参与抽奖
 * 1. 是否已经参与过
 * 2. 抽奖码是否有效(无效：被使用/不存在)
 * @param {*} openid openid
 * @param {*} lotteryCode 抽奖码
 */
const verifyAction = async (openid, lotteryCode) => {
  const command = db.command;
  console.log(openid, lotteryCode);
  const res = await db.collection('lottery_record').where(command.or([
    { openid },
    { lottery_code: lotteryCode },
  ])).get();
  // 校验 openid
  const openid_res = _.find(res.data, { openid });
  if (openid_res) return { code: 1, message: '不能重复参与' };
  // 校验抽奖码是否已经被使用
  const code_res = _.find(res.data, { lottery_code: lotteryCode });
  if (code_res) return { code: 1, message: '抽奖码无效' };
  // 校验抽奖码是否合法
  const chk_res = await db.collection('lottery_code').where({ code: lotteryCode }).count();
  if (chk_res.total <= 0) return { code: 1, message: '抽奖码无效' };
  return { code: 0, message: 'OK' };
}